class MyPromise {
  constructor(executor) {
    this.status = 'pending' // 初始状态：pending      /fulfilled/rejected
    this.value = null    // 成功的结果
    this.reason = null   // 失败的原因
    this.onFulfilledCallbacks = []   // 存放成功的函数  由then函数来存放
    this.onRejectedCallbacks = []   // 存放失败的函数
    const reslove = (value) => {
      if (this.status === 'pending') {
        this.value = value
        this.status = 'fulfilled'
        this.onFulfilledCallbacks.forEach(fn => fn(value))
      }
    }

    const reject = (reason) => {
      if (this.status === 'pending') {
        this.status = 'rejected'
        this.reason = reason
        this.onRejectedCallbacks.forEach(fn => fn(reason))
      }
    }

    executor(reslove, reject);
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value  // 函数
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
    let newPromise = new MyPromise((reslove, reject) => {
      if (this.status === 'fulfilled') {
        setTimeout(() => {
          try {
            let result = onFulfilled(this.value)   // 执行的时候是异步
            if (result instanceof MyPromise) {
              newPromise = result   // 也就是当回调里面有return 出一个对象是promise对象时返回这个对象
            }
            reslove(result)
          } catch (error) {
            reject(error)
          }
        })
      }
      if (this.status === 'rejected') {
        setTimeout(() => {
          try {
            let result = onRejected(this.reason)
            if (result instanceof MyPromise) {
              newPromise = result
            }
            reslove(result)
          } catch (error) {
            reject(error)
          }
        })
      }
      if (this.status === 'pending') {
        this.onFulfilledCallbacks.push((value) => {
          setTimeout(() => {
            try {
              const result = onFulfilled(value)
              if (result instanceof MyPromise) {
                newPromise = result
              }
              reslove(result)
            } catch (error) {
              reject(error)
            }
          })
        })
        this.onRejectedCallbacks.push((reason) => {
          setTimeout(() => {
            try {
              const result = onRejected(reason)
              if (result instanceof MyPromise) {
                newPromise = result
              }
              reslove(result)
            } catch (error) {
              reject(error)
            }
          })
        })
      }
    })

    return newPromise
  }
  catch(onRejected) {
    this.then(null, onRejected)
  }
}

function A() {
  return new MyPromise((resolve, reject) => {
    setTimeout(() => {
      reject('AAA');
    }, 1000);
  });
}

function C() {
  console.log('ccc');
}
A()
  .then(
    () => {
      C()
    },
    (err) => {
      console.log(err);
    }
  )

